import tkinter as tk
from tkinter import ttk, scrolledtext, filedialog, messagebox
import os
import pandas as pd
from datetime import datetime

# 直接定义版本号，避免循环导入问题
__version__ = "1.0.0"

from src.config.constants import UI_SETTINGS
from src.data_processing.data_import import DataImporter
from src.data_processing.data_matcher import DataMatcher
from src.data_processing.data_preprocessing import DataPreprocessor
from src.data_processing.result_processing import ResultProcessor
from src.utils.logging_utils import LoggingUtils


class MainWindow:
    """应用程序主窗口 - 按照设计规范重构的UI"""

    def __init__(self):
        """初始化主窗口"""
        self.root = tk.Tk()
        self.root.title(f"包装方案匹配系统 v{__version__}")
        width = UI_SETTINGS.get("DEFAULT_WINDOW_WIDTH", 1200)
        height = UI_SETTINGS.get("DEFAULT_WINDOW_HEIGHT", 800)
        self.root.geometry(f"{width}x{height}")
        self.root.minsize(1024, 768)

        # 初始化日志工具
        self.logging_utils = LoggingUtils()

        # 初始化数据处理组件
        self.data_importer = DataImporter()
        self.data_preprocessor = DataPreprocessor()
        self.data_matcher = DataMatcher()
        self.result_processor = ResultProcessor()

        # 存储当前数据
        self.task_data = None
        self.historical_data = None
        self.processed_data = None
        self.matched_data = None
        self.results = None
        
        # 存储文件路径
        self.task_file_path = ""
        self.historical_file_path = ""
        
        # 存储文件有效性状态
        self.task_file_valid = False
        self.historical_file_valid = False
        
        # 创建UI
        self._create_ui()
        
        # 设置样式
        self._setup_styles()

    def _create_ui(self):
        """创建用户界面 - 按照设计规范"""
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding="15")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # ========== 顶部区域 ==========
        top_frame = ttk.Frame(main_frame)
        top_frame.pack(fill=tk.X, pady=(0, 15))
        
        # ===== 左上角Logo =====
        logo_frame = ttk.LabelFrame(top_frame, text="", padding="0")
        logo_frame.pack(side=tk.LEFT, padx=(0, 30))
        
        try:
            # 加载logo图片并调整大小
            logo_path = os.path.join(os.path.dirname(__file__), "logo.png")
            self.logo_image = tk.PhotoImage(file=logo_path)
            
            # 调整logo大小，使其与文件选择区域高度一致
            # 获取logo图片原始尺寸
            original_width = self.logo_image.width()
            original_height = self.logo_image.height()
            
            # 设置目标高度（根据文件选择区域高度调整）
            target_height = 60  # 与文件选择区域高度保持一致
            
            # 计算缩放比例并调整大小
            scale_factor = target_height / original_height
            target_width = int(original_width * scale_factor)
            
            # 计算subsample参数（取整）
            subsample_x = max(1, int(original_width / target_width))
            subsample_y = max(1, int(original_height / target_height))
            
            # 调整logo图片大小
            self.logo_image = self.logo_image.subsample(subsample_x, subsample_y)
            
            self.logo_label = ttk.Label(logo_frame, image=self.logo_image)
            self.logo_label.pack(padx=0, pady=0)
        except Exception as e:
            self.log_message(f"警告: 无法加载logo图片 - {str(e)}")
            self.logo_label = ttk.Label(logo_frame, text="瀚越包装")
            self.logo_label.pack(padx=10, pady=10)
        
        # ===== 文件选择区域 =====
        file_selection_frame = ttk.Frame(top_frame)
        file_selection_frame.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=(10, 0))
        
        # 任务数据表选择
        task_file_frame = ttk.LabelFrame(file_selection_frame, text="翰越包装设计计划", padding="5")
        task_file_frame.pack(fill=tk.X, pady=(0, 8))
        
        self.task_file_btn = ttk.Button(
            task_file_frame, 
            text="选择文件", 
            command=self._select_task_file
        )
        self.task_file_btn.pack(fill=tk.X, expand=True, padx=5, pady=3)
        
        # 文件路径和状态显示在按钮下方
        path_frame = ttk.Frame(task_file_frame)
        path_frame.pack(fill=tk.X, expand=True, padx=5, pady=(2, 0))
        
        self.task_file_path_var = tk.StringVar(value="未选择文件")
        self.task_file_path_label = ttk.Label(
            path_frame, 
            textvariable=self.task_file_path_var, 
            anchor="w",
            wraplength=0,  # 允许文本自动换行
            justify=tk.LEFT,
            font=('Microsoft YaHei', 9)  # 使用稍小的字体
        )
        self.task_file_path_label.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        self.task_file_status_var = tk.StringVar(value="无效")
        self.task_file_status_label = ttk.Label(
            path_frame, 
            textvariable=self.task_file_status_var, 
            width=5, 
            foreground="red",
            font=('Microsoft YaHei', 9, 'bold')
        )
        self.task_file_status_label.pack(side=tk.RIGHT, padx=(5, 0))
        
        # 历史包装数据选择
        historical_file_frame = ttk.LabelFrame(file_selection_frame, text="历史包装数据", padding="5")
        historical_file_frame.pack(fill=tk.X)
        
        self.historical_file_btn = ttk.Button(
            historical_file_frame, 
            text="选择文件", 
            command=self._select_historical_file
        )
        self.historical_file_btn.pack(fill=tk.X, expand=True, padx=5, pady=3)
        
        # 文件路径和状态显示在按钮下方
        path_frame = ttk.Frame(historical_file_frame)
        path_frame.pack(fill=tk.X, expand=True, padx=5, pady=(2, 0))
        
        self.historical_file_path_var = tk.StringVar(value="未选择文件")
        self.historical_file_path_label = ttk.Label(
            path_frame, 
            textvariable=self.historical_file_path_var, 
            anchor="w",
            wraplength=0,  # 允许文本自动换行
            justify=tk.LEFT,
            font=('Microsoft YaHei', 9)  # 使用稍小的字体
        )
        self.historical_file_path_label.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        self.historical_file_status_var = tk.StringVar(value="无效")
        self.historical_file_status_label = ttk.Label(
            path_frame, 
            textvariable=self.historical_file_status_var, 
            width=5, 
            foreground="red",
            font=('Microsoft YaHei', 9, 'bold')
        )
        self.historical_file_status_label.pack(side=tk.RIGHT, padx=(5, 0))
        
        # ========== 步骤显示区域 ==========
        steps_frame = ttk.LabelFrame(main_frame, text="处理步骤", padding="10")
        steps_frame.pack(fill=tk.X, pady=(0, 15))
        
        # 创建步骤显示标签
        self.steps_var = tk.StringVar(value="请选择任务数据表和历史包装数据文件，然后点击'开始'按钮")
        self.steps_label = ttk.Label(
            steps_frame, 
            textvariable=self.steps_var,
            font=('Microsoft YaHei', 10),
            wraplength=0,  # 允许文本自动换行
            justify=tk.LEFT,
            anchor="w"
        )
        self.steps_label.pack(fill=tk.X, expand=True)
        
        # ========== 中间区域 ==========
        middle_frame = ttk.Frame(main_frame)
        middle_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 15))
        
        # ===== 左侧 - 操作区 =====
        left_frame = ttk.LabelFrame(middle_frame, text="操作区", padding="10")
        left_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10))
        left_frame.config(width=200)
        
        # 开始按钮
        self.start_btn = ttk.Button(
            left_frame, 
            text="开始", 
            width=15, 
            command=self._start_process,
            state=tk.DISABLED
        )
        self.start_btn.pack(pady=10)
        
        # 导出按钮已移除，改为在存储文件阶段自动弹出路径选择窗口
        
        # 清空按钮
        self.clear_btn = ttk.Button(
            left_frame, 
            text="清空", 
            width=15, 
            command=self._clear_all
        )
        self.clear_btn.pack(pady=10)
        
        # 软件说明按钮
        self.help_btn = ttk.Button(
            left_frame, 
            text="软件说明", 
            width=15, 
            command=self._show_software_description
        )
        self.help_btn.pack(pady=10)
        
        # 退出按钮
        self.exit_btn = ttk.Button(
            left_frame, 
            text="退出", 
            width=15, 
            command=self.root.quit
        )
        self.exit_btn.pack(pady=10)
        
        # ===== 右侧 - 日志和数据区域 =====
        right_frame = ttk.Frame(middle_frame)
        right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
        
        # 全局进度条
        progress_frame = ttk.LabelFrame(right_frame, text="总进度", padding="10")
        progress_frame.pack(fill=tk.X, pady=(0, 10))
        
        self.global_progress_var = tk.DoubleVar(value=0)
        self.global_progress_bar = ttk.Progressbar(
            progress_frame, 
            variable=self.global_progress_var, 
            orient=tk.HORIZONTAL, 
            length=100, 
            mode="determinate"
        )
        self.global_progress_bar.pack(fill=tk.X, expand=True)
        
        self.global_progress_label = ttk.Label(
            progress_frame, 
            text="0%", 
            width=5, 
            anchor="center"
        )
        self.global_progress_label.pack(side=tk.RIGHT, padx=5)
        
        # 阶段进度条 - 数据预处理
        preprocess_frame = ttk.LabelFrame(right_frame, text="数据预处理进度", padding="10")
        preprocess_frame.pack(fill=tk.X, pady=(0, 10))
        
        self.preprocess_progress_var = tk.DoubleVar(value=0)
        self.preprocess_progress_bar = ttk.Progressbar(
            preprocess_frame, 
            variable=self.preprocess_progress_var, 
            orient=tk.HORIZONTAL, 
            length=100, 
            mode="determinate"
        )
        self.preprocess_progress_bar.pack(fill=tk.X, expand=True)
        
        # 阶段进度条 - 数据匹配
        matching_frame = ttk.LabelFrame(right_frame, text="数据匹配进度", padding="10")
        matching_frame.pack(fill=tk.X, pady=(0, 10))
        
        self.matching_progress_var = tk.DoubleVar(value=0)
        self.matching_progress_bar = ttk.Progressbar(
            matching_frame, 
            variable=self.matching_progress_var, 
            orient=tk.HORIZONTAL, 
            length=100, 
            mode="determinate"
        )
        self.matching_progress_bar.pack(fill=tk.X, expand=True)
        
        # 日志区域
        log_frame = ttk.LabelFrame(right_frame, text="数据运算日志", padding="10")
        log_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建日志文本框
        self.log_text = scrolledtext.ScrolledText(
            log_frame, 
            wrap=tk.WORD, 
            width=80, 
            height=20,
            font=("Microsoft YaHei", 10)
        )
        self.log_text.pack(fill=tk.BOTH, expand=True)
        self.log_text.config(state=tk.DISABLED)  # 只读
        
        # ========== 底部状态栏 ==========
        self.status_var = tk.StringVar(value="就绪")
        status_bar = ttk.Label(
            self.root, 
            textvariable=self.status_var,
            relief=tk.SUNKEN, 
            anchor=tk.W,
            padding=(10, 5)
        )
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
        
        # 初始日志
        self.log_message("欢迎使用包装方案匹配系统")
        self.log_message("请选择任务数据表和历史包装数据文件，然后点击'开始'按钮")

    def _setup_styles(self):
        """设置UI样式"""
        style = ttk.Style()
        
        # 设置按钮样式
        style.configure(
            "TButton",
            font=("Microsoft YaHei", 10),
            padding=5
        )
        
        # 设置标签样式
        style.configure(
            "TLabel",
            font=("Microsoft YaHei", 10)
        )
        
        # 设置框架样式
        style.configure(
            "TFrame",
            background="#f0f0f0"
        )
        
        # 设置标签框架样式
        style.configure(
            "TLabelframe",
            font=("Microsoft YaHei", 10, "bold"),
            padding=10
        )

    def _select_task_file(self):
        """选择任务数据表文件"""
        file_path = filedialog.askopenfilename(
            title="选择翰越包装设计计划",
            filetypes=[("Excel Files", "*.xlsx *.xls")]
        )
        
        if file_path:
            self.task_file_path = file_path
            self.task_file_path_var.set(file_path)
            
            # 验证文件
            try:
                self.task_data = self.data_importer.import_excel_file(file_path)
                self.task_file_valid = True
                self.task_file_status_var.set("有效")
                self.task_file_status_label.config(foreground="green")
                self.log_message(f"成功加载任务数据表: {file_path}")
            except Exception as e:
                self.task_file_valid = False
                self.task_file_status_var.set("无效")
                self.task_file_status_label.config(foreground="red")
                self.log_message(f"任务数据表无效: {str(e)}")
        
        # 更新开始按钮状态
        self._update_start_button_state()

    def _select_historical_file(self):
        """选择历史包装数据文件"""
        file_path = filedialog.askopenfilename(
            title="选择历史包装数据",
            filetypes=[("Excel Files", "*.xlsx *.xls")]
        )
        
        if file_path:
            self.historical_file_path = file_path
            self.historical_file_path_var.set(file_path)
            
            # 验证文件
            try:
                self.historical_data = self.data_importer.import_excel_file(file_path)
                self.historical_file_valid = True
                self.historical_file_status_var.set("有效")
                self.historical_file_status_label.config(foreground="green")
                self.log_message(f"成功加载历史包装数据: {file_path}")
            except Exception as e:
                self.historical_file_valid = False
                self.historical_file_status_var.set("无效")
                self.historical_file_status_label.config(foreground="red")
                self.log_message(f"历史包装数据无效: {str(e)}")
        
        # 更新开始按钮状态
        self._update_start_button_state()

    def _update_start_button_state(self):
        """更新开始按钮状态"""
        if self.task_file_valid and self.historical_file_valid:
            self.start_btn.config(state=tk.NORMAL)
            self.log_message("所有文件已就绪，可以开始处理")
        else:
            self.start_btn.config(state=tk.DISABLED)

    def _start_process(self):
        """开始处理任务"""
        if not self.task_file_valid or not self.historical_file_valid:
            self.log_message("错误: 请先选择有效的任务数据表和历史包装数据")
            return
        
        # 禁用开始按钮
        self.start_btn.config(state=tk.DISABLED)
        
        # 清空进度条
        self.global_progress_var.set(0)
        self.global_progress_label.config(text="0%")
        self.preprocess_progress_var.set(0)
        self.matching_progress_var.set(0)
        
        # 开始处理（使用after来避免UI卡死）
        self.root.after(100, self._process_task)

    def _process_task(self):
        """处理任务的主要逻辑"""
        try:
            # ========== 1. 数据导入 ==========
            self.log_message("=" * 50)
            self.log_message("【数据导入】开始")
            self.status_var.set("数据导入中...")
            self.steps_var.set("步骤1/4：数据导入 - 正在加载和验证任务数据表与历史包装数据...")
            self.root.update_idletasks()
            
            # 已经在选择文件时导入了数据，这里只需要确认
            self.log_message(f"任务数据表记录数: {len(self.task_data)}")
            self.log_message(f"历史包装数据记录数: {len(self.historical_data)}")
            self.log_message("【数据导入】完成")
            
            # 更新进度
            self._update_global_progress(10)
            self.root.update_idletasks()
            
            # ========== 2. 数据预处理 ==========
            self.log_message("=" * 50)
            self.log_message("【数据预处理】开始")
            self.status_var.set("数据预处理中...")
            self.steps_var.set("步骤2/4：数据预处理 - 正在进行数据格式化、合并、包装类型确定和产品归类...")
            self.root.update_idletasks()
            
            # 格式化
            self.log_message("  【格式化】开始")
            self.processed_data = self.data_preprocessor.clean_data(self.task_data)
            self._update_preprocess_progress(25)
            self.root.update_idletasks()
            self.log_message("  【格式化】完成")
            
            # 合并
            self.log_message("  【合并】开始")
            # 实际处理中可能需要合并数据
            self._update_preprocess_progress(50)
            self.root.update_idletasks()
            self.log_message("  【合并】完成")
            
            # 确定包装类型
            self.log_message("  【确定包装类型】开始")
            self.processed_data = self.data_preprocessor.standardize_data(self.processed_data)
            self._update_preprocess_progress(75)
            self.root.update_idletasks()
            self.log_message("  【确定包装类型】完成")
            
            # 确定产品归类
            self.log_message("  【确定产品归类】开始")
            # 实际处理中可能需要归类产品
            self._update_preprocess_progress(100)
            self.root.update_idletasks()
            self.log_message("  【确定产品归类】完成")
            
            self.log_message("【数据预处理】完成")
            
            # 更新进度
            self._update_global_progress(40)
            self.root.update_idletasks()
            
            # ========== 3. 数据匹配分类及方案处理 ==========
            self.log_message("=" * 50)
            self.log_message("【数据匹配分类及方案处理】开始")
            self.status_var.set("数据匹配中...")
            self.steps_var.set("步骤3/4：数据匹配分类及方案处理 - 正在根据历史数据为任务数据匹配最佳包装方案...")
            self.root.update_idletasks()
            
            # 设置进度回调
            def matching_progress_callback(progress):
                self._update_matching_progress(progress)
                self._update_global_progress(40 + progress * 0.4)
                self.root.update_idletasks()
            
            # 执行匹配 - 使用正确的方法链
            # 1. 先进行规格型号匹配
            self.log_message("  【规格型号匹配】开始")
            matched_data = self.data_matcher.match_specification(
                self.processed_data, 
                self.historical_data
            )
            matching_progress_callback(30)  # 更新进度
            self.log_message("  【规格型号匹配】完成")
            
            # 2. 对匹配后的数据进行分类
            self.log_message("  【数据分类】开始")
            classified_data = self.data_matcher.classify_data(matched_data)
            matching_progress_callback(60)  # 更新进度
            self.log_message("  【数据分类】完成")
            
            # 3. 执行匹配策略
            self.log_message("  【执行匹配策略】开始")
            self.matched_data = self.data_matcher.execute_matching_strategy(classified_data)
            matching_progress_callback(100)  # 更新进度
            self.log_message("  【执行匹配策略】完成")
            
            self.log_message("【数据匹配分类及方案处理】完成")
            
            # 更新进度
            self._update_global_progress(80)
            self.root.update_idletasks()
            
            # ========== 4. 后处理 ==========
            self.log_message("=" * 50)
            self.log_message("【后处理】开始")
            self.status_var.set("后处理中...")
            self.steps_var.set("步骤4/4：后处理 - 正在进行数据输出、表格整理和数据验证...")
            self.root.update_idletasks()
            
            # 数据输出
            self.log_message("  【数据输出】开始")
            # 先处理结果
            processed_results = self.result_processor.process_results(self.matched_data)
            # 再优化结果
            self.results = self.result_processor.optimize_results(processed_results)
            self._update_global_progress(85)
            self.root.update_idletasks()
            self.log_message("  【数据输出】完成")
            
            # 表格整理
            self.log_message("  【表格整理】开始")
            # 实际处理中可能需要整理表格
            self._update_global_progress(90)
            self.root.update_idletasks()
            self.log_message("  【表格整理】完成")
            
            # 数据验证
            self.log_message("  【数据验证】开始")
            # 实际处理中可能需要验证数据
            self._update_global_progress(95)
            self.root.update_idletasks()
            self.log_message("  【数据验证】完成")
            
            # 完成
            self.log_message("【后处理】完成")
            
            # 更新进度
            self._update_global_progress(100)
            self.root.update_idletasks()
            
            # 处理完成
            self.log_message("=" * 50)
            self.log_message("✅ 处理完成！")
            self.status_var.set("处理完成")
            self.steps_var.set("处理完成！正在为您导出结果文件...")
            
            # 自动弹出路径选择窗口进行导出
            self._auto_export_results()
            
            # 显示结果统计
            if self.results is not None and not self.results.empty:
                self.log_message(f"匹配结果统计: 总记录数 {len(self.results)}")
                # 可以添加更多统计信息
                
        except Exception as e:
            self.log_message(f"❌ 处理过程中发生错误: {str(e)}")
            self.status_var.set("处理失败")
            messagebox.showerror("错误", f"处理过程中发生错误: {str(e)}")
        finally:
            # 确保开始按钮可用
            if self.task_file_valid and self.historical_file_valid:
                self.start_btn.config(state=tk.NORMAL)
    
    def _auto_export_results(self):
        """自动导出结果"""
        if self.results is None or self.results.empty:
            self.log_message("错误: 没有可导出的结果")
            messagebox.showerror("错误", "没有可导出的结果")
            return
        
        # 获取默认保存路径（任务表格所在路径）
        default_dir = os.path.dirname(self.task_file_path) if self.task_file_path else os.getcwd()
        
        # 获取当前时间作为默认文件名的一部分
        current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
        default_filename = f"包装方案匹配结果_{current_time}.xlsx"
        
        # 显示保存对话框
        file_path = filedialog.asksaveasfilename(
            title="保存结果文件",
            defaultextension=".xlsx",
            filetypes=[("Excel Files", "*.xlsx")],
            initialdir=default_dir,
            initialfile=default_filename
        )
        
        if file_path:
            try:
                # 导出结果
                self.result_processor.export_results(self.results, file_path)
                self.log_message(f"成功导出结果到: {file_path}")
                self.status_var.set(f"成功导出结果到: {file_path}")
                messagebox.showinfo("成功", f"结果已成功导出到:\n{file_path}")
            except Exception as e:
                self.log_message(f"导出失败: {str(e)}")
                self.status_var.set("导出失败")
                messagebox.showerror("错误", f"导出失败: {str(e)}")


    def _clear_all(self):
        """清空所有数据和状态"""
        # 清空数据
        self.task_data = None
        self.historical_data = None
        self.processed_data = None
        self.matched_data = None
        self.results = None
        
        # 清空文件路径
        self.task_file_path = ""
        self.historical_file_path = ""
        
        # 清空有效性状态
        self.task_file_valid = False
        self.historical_file_valid = False
        
        # 更新UI
        self.task_file_path_var.set("未选择文件")
        self.task_file_status_var.set("无效")
        self.task_file_status_label.config(foreground="red")
        
        self.historical_file_path_var.set("未选择文件")
        self.historical_file_status_var.set("无效")
        self.historical_file_status_label.config(foreground="red")
        
        # 清空进度条
        self.global_progress_var.set(0)
        self.global_progress_label.config(text="0%")
        self.preprocess_progress_var.set(0)
        self.matching_progress_var.set(0)
        
        # 禁用按钮
        self.start_btn.config(state=tk.DISABLED)
        
        # 更新状态
        self.status_var.set("就绪")
        
        # 更新步骤显示
        self.steps_var.set("请选择任务数据表和历史包装数据文件，然后点击'开始'按钮")
        
        # 清空日志（保留最初的欢迎信息）
        self.log_text.config(state=tk.NORMAL)
        self.log_text.delete(1.0, tk.END)
        self.log_text.config(state=tk.DISABLED)
        
        # 重新添加欢迎信息
        self.log_message("欢迎使用包装方案匹配系统")
        self.log_message("请选择任务数据表和历史包装数据文件，然后点击'开始'按钮")

    def _show_software_description(self):
        """显示软件说明"""
        description = (
            "包装方案匹配系统\n\n"
            "版本: " + __version__ + "\n\n"
            "功能说明:\n"
            "1. 翰越包装设计计划: 选择包含包装任务的Excel文件\n"
            "2. 历史包装数据: 选择包含历史包装方案的Excel文件\n"
            "3. 开始: 启动包装方案匹配过程\n"
            "4. 导出结果: 将匹配结果导出为Excel文件\n"
            "5. 清空: 清除所有已加载的数据和状态\n\n"
            "处理流程:\n"
            "1. 数据导入\n"
            "2. 数据预处理\n"
            "   - 格式化\n"
            "   - 合并\n"
            "   - 确定包装类型\n"
            "   - 确定产品归类\n"
            "3. 数据匹配分类及方案处理\n"
            "4. 后处理\n"
            "   - 数据输出\n"
            "   - 表格整理\n"
            "   - 数据验证\n"
            "   - 完成\n\n"
            "注意事项:\n"
            "- 请确保选择的Excel文件格式正确\n"
            "- 处理过程中请勿关闭程序\n"
            "- 导出结果时，默认保存路径为任务表格所在路径"
        )
        
        # 创建说明窗口
        help_window = tk.Toplevel(self.root)
        help_window.title("软件说明")
        help_window.geometry("600x600")
        help_window.resizable(True, True)
        
        # 创建滚动文本框
        help_text = scrolledtext.ScrolledText(
            help_window, 
            wrap=tk.WORD, 
            font=("Microsoft YaHei", 10)
        )
        help_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        help_text.insert(tk.END, description)
        help_text.config(state=tk.DISABLED)  # 只读
        
        # 添加关闭按钮
        close_btn = ttk.Button(
            help_window, 
            text="关闭", 
            command=help_window.destroy
        )
        close_btn.pack(pady=10)

    def log_message(self, message):
        """记录消息到日志区域"""
        timestamp = datetime.now().strftime("%H:%M:%S")
        log_entry = f"[{timestamp}] {message}\n"
        
        # 更新日志文本框
        self.log_text.config(state=tk.NORMAL)
        self.log_text.insert(tk.END, log_entry)
        self.log_text.see(tk.END)  # 滚动到底部
        self.log_text.config(state=tk.DISABLED)
        
        # 同时写入到日志文件
        self.logging_utils.info(message)

    def _update_global_progress(self, progress):
        """更新全局进度条"""
        self.global_progress_var.set(progress)
        self.global_progress_label.config(text=f"{progress}%")

    def _update_preprocess_progress(self, progress):
        """更新数据预处理进度条"""
        self.preprocess_progress_var.set(progress)

    def _update_matching_progress(self, progress):
        """更新数据匹配进度条"""
        self.matching_progress_var.set(progress)

    def run(self):
        """运行应用程序"""
        self.root.mainloop()
